/*
 * Copyright (c) 2025 EasyAdmin
 * All rights reserved.
 *
 * This file is part of the [EasAdmin] project.
 * Unauthorized copying of this file, via any medium, is strictly prohibited.
 * Proprietary and confidential.
 *
 * Author: EasyAdmin ( 1073602@qq.com )
 * Website: https://www.xhxiao.com
 */
package com.easy.module.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easy.framework.cache.utils.DictUtil;
import com.easy.framework.common.enums.CommonStatus;
import com.easy.framework.common.exception.ServiceException;
import com.easy.framework.common.utils.ConvertUtil;
import com.easy.framework.common.utils.Func;
import com.easy.module.system.entity.SysDict;
import com.easy.module.system.entity.SysDictData;
import com.easy.module.system.mapper.SysDictMapper;
import com.easy.module.system.query.SysDictQuery;
import com.easy.module.system.service.ISysDictDataService;
import com.easy.module.system.service.ISysDictService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 字典类型表 Service业务
 *
 * @author EasyAdmin ( 1073602@qq.com )
 * @date 2025-08-19
 */
@RequiredArgsConstructor
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements ISysDictService
{

    private final ISysDictDataService dictDataService;

    /**
     * 项目启动时，初始化字典到缓存
     */
    @PostConstruct
    public void init() {
        loadingDictCache();
    }


    /**
     * 查询字典代码列表
     *
     * @param query 字典代码
     * @return 字典代码
     */
    @Override
    public List<SysDict> list(SysDictQuery query)
    {
        return list(lambdaQueryOptional(query).orElse(lambdaQueryWrapper()).orderByDesc(SysDict::getCreatedAt));
    }

    /**
     * 新增字典代码
     *
     * @param dto 字典代码
     * @return 结果
     */
    @Override
    public boolean add(SysDict dto)
    {
        boolean sign = save(dto);
        if (sign) {
            DictUtil.setDictCache(dto.getDictCode(), null);
        }
        return sign;
    }

    /**
     * 修改字典代码
     *
     * @param dto 字典代码
     * @return 结果
     */
    @Override
    @Transactional
    public boolean update(SysDict dto)
    {
        SysDict sysDict = getById(dto.getId());
        dictDataService.updateDictCode(sysDict.getDictCode(), dto.getDictCode());
        boolean sign = updateById(dto);
        if (sign) {
            dictDataService.setDictionaryCache(dto.getDictCode());
        }
        return sign;
    }

    /**
     * 批量删除字典代码
     *
     * @param dictIds 需要删除的字典代码主键
     * @return 结果
     */
    @Override
    public boolean deleteByIds(Long[] dictIds)
    {
        for (Long dictId : dictIds) {
            SysDict dictCode = getById(dictId);
            if (dictDataService.countByDictCode(dictCode.getDictCode()) > 0L) {
                throw new ServiceException(String.format("%1$s已分配,不能删除" , dictCode.getDictName()));
            }
            removeById(dictId);
            DictUtil.removeDictCache(dictCode.getDictCode());
        }
        return true;
    }


    /**
     * 校验字典代码称是否唯一
     *
     * @param dict 字典代码
     * @return 结果
     */
    @Override
    public boolean checkDictCodeUnique(SysDict dict) {
        Long dictId = Func.isNull(dict.getId()) ? -1L : dict.getId();
        SysDict dictCode = getByDictCode(dict.getDictCode());
        if (Func.isNotEmpty(dictCode) && dictCode.getId().longValue() != dictId.longValue()) {
            return false;
        }
        return true;
    }


    /**
     * 加载字典缓存数据
     */
    @Override
    public void loadingDictCache() {
        Map<String, List<SysDictData>> dictDataMap = dictDataService.list(Wrappers.<SysDictData>lambdaQuery()
                .eq(SysDictData::getStatus,CommonStatus.enabled.getValue()))
                .stream().collect(Collectors.groupingBy(SysDictData::getDictCode));
        for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
            dictDataService.setDictionaryCache(entry.getKey(),entry.getValue());
        }
    }

    /**
     * 清空字典缓存数据
     */
    @Override
    public void clearDictCache() {
        DictUtil.clearDictCache();
    }

    /**
     * 重置字典缓存数据
     */
    @Override
    public void resetDictCache() {
        clearDictCache();
        loadingDictCache();
    }

    @Override
    public SysDict getByDictCode(String dictCode) {
        return getOne(Wrappers.<SysDict>lambdaQuery().eq(SysDict::getDictCode, dictCode),false);
    }
}
